
package com.elong.common.http;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URI;
import java.util.List;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CookieStore;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.client.utils.URIUtils;
import org.apache.http.config.ConnectionConfig;
import org.apache.http.conn.ConnectionKeepAliveStrategy;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.protocol.HttpContext;

import com.elong.common.util.LoggerUtil;



/**
 * @ClassName: HttpUtil

 * @Description: TODO

 * @author Guanguo.Gao

 * @date 2014年8月25日 上午11:49:29

 * @version V1.0
 */
public class HttpUtil {
    
    public  static final Integer BUFF_SIZE = 8 * 1024; 
    
    public static void main(String[] args) throws ClientProtocolException, IOException {
        HttpUtil.httpRedirect("http://www.jingdong.com");
    }
    
    /**
     * @Description: 从response中获得结果
     * @param response
     * @return
     * @throws
     */
    public static HttpResult getContentFromResponse(HttpResponse response){       
        HttpResult result = new HttpResult();
        StringBuffer buffer = new StringBuffer();
        HttpEntity entity = response.getEntity();
        result.setRetCode(response.getStatusLine().getStatusCode());
        try {
            if(entity != null){
                InputStream instream = entity.getContent();
                try{
                    BufferedReader reader = new BufferedReader(new InputStreamReader(instream));
                    String content;
                    while((content=reader.readLine()) != null){
                        buffer.append(content);
                    }
                }finally{
                    instream.close();
                }
            }
        } catch (Exception e) {
            LoggerUtil.error("connect error", e);
        }
        //设置提交后的页面
        Header locationHeader = response.getFirstHeader("Location");
        if (locationHeader == null) {  
            result.setRedirectUrl("");  
        }else {
            result.setRedirectUrl(locationHeader.getValue());  
        }
        //设置cookie
        String cookie = retResponseHeader(response, "Set-Cookie");
        result.setCookie(cookie);
        
        //设置cookiestore
        
        //设置返回内容
        result.setRetContent(buffer.toString());
        return result;
    }
    
    /**
     * @Description: 连接保持策略
     * @return
     * @throws
     */
    public static ConnectionKeepAliveStrategy getKeepAliveStrategy(){
        ConnectionKeepAliveStrategy keepAliveStra = new DefaultConnectionKeepAliveStrategy(){
            
            @Override
            public long getKeepAliveDuration(
                    HttpResponse response,
                    HttpContext context){
                long keepAlive = super.getKeepAliveDuration(response, context);
                if(keepAlive == -1){
                    // Keep connections alive 5 seconds if a keep-alive value
                    // has not be explicitly set by the server
                    keepAlive = 5000;
                }
                return keepAlive;
            }
        };
        return keepAliveStra;
    }
    
    public static CloseableHttpClient retHttpClient(){
        return HttpClients.custom().setKeepAliveStrategy(getKeepAliveStrategy()).build();
    }
    
    public static void closeHttpClient(CloseableHttpClient client){
        try {
            client.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    /**
     * @Description: redirect设置
     * 
     * @throws
     */
    public static void httpRedirect(String url){
        CloseableHttpClient httpclient = HttpClients.createDefault();
        HttpClientContext context = HttpClientContext.create();
        HttpGet httpget = new HttpGet(url);
        CloseableHttpResponse response = null;
        try {
            response = httpclient.execute(httpget, context);
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            try {
                response.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    /**
     * @Description: get 300之后的跳转地址
     * @param response
     * @param context
     * @return
     * @throws
     */
    public static String getRedirectUrl(HttpGet httpget, HttpResponse response, HttpClientContext context){
        try {
            HttpHost target = context.getTargetHost();
            List<URI> redirectLocations = context.getRedirectLocations();
            URI location = URIUtils.resolve(httpget.getURI(), target.toURI());
            return location.toASCIIString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }
    
    /**
     * @Description: 获取属性
     * 一般Set-Cookie只需要第一个值，其他的都不需要
     * @param response
     * @param key
     * @return
     * @throws
     */
    public static String retResponseHeader(HttpResponse response, String key){
        Header h1 = response.getFirstHeader(key);
        if(h1 == null)
            return "";
        return h1.getValue();
    }
    
    /**
     * @Description: 获得httpclient
     * @return
     * @throws
     */
    public static HttpClient getHttpClient(Integer retryCount){
        ConnectionConfig connConfig = ConnectionConfig.custom()
                .setBufferSize(BUFF_SIZE)
                .build();
        
        CookieStore cookieStore = new BasicCookieStore();
        HttpClient client = HttpClients.custom()
                .setRetryHandler(new DefaultHttpRequestRetryHandler(retryCount, true))
                .setRedirectStrategy(new CustomRedirectStrategy())
                .setDefaultConnectionConfig(connConfig)
                .setKeepAliveStrategy(getKeepAliveStrategy())
                .setDefaultCookieStore(cookieStore)
                .build();
        return client;
    }

}
